Skip to content

Fall back to global trace config when a span's own config is null - #12374

Open
dougqh wants to merge 1 commit into
masterfrom
dougqh/fix-traceconfig-null-extracted-span
Open

Fall back to global trace config when a span's own config is null#12374
dougqh wants to merge 1 commit into
masterfrom
dougqh/fix-traceconfig-null-extracted-span

Conversation

@dougqh

@dougqh dougqh commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

What Does This Do

AgentTracer.traceConfig(AgentSpan) returned null whenever the given span itself reported a null TraceConfig (e.g. an ExtractedSpan, which wraps only a remote/propagated context and has no local trace config). It now falls back to the global trace config in that case, the same fallback the method already used when the span itself was null.

Added AgentTracerTest covering: a null span, a span with its own config, and the regression case (an extracted span whose own traceConfig() is null).

Motivation

Several logging instrumentations call traceConfig(span).isLogsInjectionEnabled() after only null-checking span (not the returned TraceConfig), e.g. LogbackLoggerInstrumentation$CallAppendersAdvice:

if (span != null && traceConfig(span).isLogsInjectionEnabled()) {

When the active span is an ExtractedSpan, traceConfig(span) returned null, causing a NullPointerException. It's swallowed by the tracer's own advice-exception handler so it never breaks the instrumented app, but it shows up as a spurious error-tracking issue, misattributed to whatever code happens to be on the calling thread at the time (in the case that prompted this fix, an rxjava2 observer chain, since Logger.callAppenders was invoked synchronously from deep inside it).

The same unguarded pattern is duplicated across five logging integrations (logback, log4j1, log4j2, jboss-logmanager, tinylog), so fixing it at the shared source (AgentTracer.traceConfig) covers all of them at once instead of patching each call site.

Additional Notes

Investigated via a Datadog Error Tracking issue whose stack trace pointed at datadog.trace.instrumentation.rxjava2.TracingSingleObserver.onSuccess — that attribution was a red herring; root-cause writeup posted as a comment on the issue.

Contributor Checklist

  • Format the title according to the contribution guidelines
  • Assign the type: and (comp: or inst:) labels in addition to any other useful labels
  • Avoid using close, fix, or any linking keywords when referencing an issue
  • Update the CODEOWNERS file on source file addition, migration, or deletion (n/a — no files added/moved)
  • Update public documentation with any new configuration flags or behaviors (n/a — no config/behavior change)
  • Once approved, use merge queue to merge the PR

Jira ticket: [none]

AgentTracer.traceConfig(AgentSpan) returned null for an ExtractedSpan
(a span wrapping only a remote/propagated context, not yet a local
span), since ExtractedSpan.traceConfig() intentionally reports null.
Several logging instrumentations (logback, log4j1, log4j2,
jboss-logmanager, tinylog) call traceConfig(span).isLogsInjectionEnabled()
without a further null check, so this surfaced as an NPE swallowed by
the tracer's own advice-exception handler and misattributed in error
tracking to whatever code happened to be on the calling thread.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

public static TraceConfig traceConfig(final AgentSpan span) {
return null != span ? span.traceConfig() : traceConfig();
final TraceConfig config = span == null ? null : span.traceConfig();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

span.traceConfig returns null for ExtractedSpan.
Arguably, we'd be better fixing ExtracedSpan, but I'm curious what others think.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO fixing ExtractedSpan to return AgentTracer.traceConfig() would be better.

@dougqh
dougqh force-pushed the dougqh/fix-traceconfig-null-extracted-span branch from b699de3 to 83e57f8 Compare September 2, 2026 02:43
@dougqh
dougqh marked this pull request as ready for review September 2, 2026 02:43
@dougqh
dougqh requested a review from a team as a code owner September 2, 2026 02:43
@dougqh
dougqh requested review from mcculls and removed request for a team September 2, 2026 02:43
@dd-octo-sts dd-octo-sts Bot added the tag: ai generated Largely based on code generated by an AI or LLM label Sep 2, 2026
@dd-octo-sts

dd-octo-sts Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Hi! 👋 Thanks for your pull request! 🎉

To help us review it, please make sure to:

  • Add at least one type, and one component or instrumentation label to the pull request

If you need help, please check our contributing guidelines.

@dougqh dougqh added type: bug fix Bug fix comp: core Tracer core labels Sep 2, 2026

@datadog-datadog-prod-us1 datadog-datadog-prod-us1 Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Datadog Autotest: PASS

More details

The fallback keeps a span-specific trace configuration. It uses the global trace configuration only when the span or its configuration is null.

Was this helpful? React 👍 or 👎

Open Bits AI session

🤖 Datadog Autotest · Commit 83e57f8 · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest

@datadog-datadog-prod-us1

This comment has been minimized.

@dd-octo-sts

dd-octo-sts Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

🟢 Java Benchmark SLOs — All performance SLOs passed

Suite Status
Startup 🟢 pass

SLO thresholds are defined here based on automatically generated metrics. A warning is raised when results are within 5% of the threshold.

PR vs. master results
Scenario Candidate master Δ (95% CI of mean)
startup:insecure-bank:iast:Agent 14.05 s 13.94 s [-0.1%; +1.6%] (no difference)
startup:insecure-bank:tracing:Agent 13.02 s 13.02 s [-1.0%; +0.9%] (no difference)
startup:petclinic:appsec:Agent 17.53 s 17.30 s [+0.4%; +2.4%] (maybe worse)
startup:petclinic:iast:Agent 17.43 s 17.52 s [-1.4%; +0.3%] (no difference)
startup:petclinic:profiling:Agent 17.62 s 17.23 s [+1.1%; +3.4%] (significantly worse)
startup:petclinic:sca:Agent 17.52 s 17.45 s [-0.5%; +1.3%] (no difference)
startup:petclinic:tracing:Agent 16.56 s 16.25 s [-2.5%; +6.3%] (no difference)

Commit: 83e57f8d · CI Pipeline · Benchmarking Platform UI


Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: core Tracer core tag: ai generated Largely based on code generated by an AI or LLM type: bug fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants